import threading
import time
from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib import parse
import cv2
import subprocess
import paho.mqtt.publish as publish
import paho.mqtt.client as mqtt
import ssl
import sys, time


auth_token = '112233'

video_dict = {}
video_read_time_dict = {}


class ShellHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        # auth_flag = False
        # headers = self.headers.items()
        # for name, value in headers:
        #     if name == "Authorization":
        #         if value == auth_token:
        #             auth_flag = True
        #             break
        # if not auth_flag:
        #     self.response(401, "Authentication failed")
        #     return

        # ParseResult(scheme='', netloc='', path='/a/v/b', params='', query='q=1', fragment='')
        parsed_result = parse.urlparse(self.path)
        params = parsed_result.query
        url_path = parsed_result.path
        if not params:
            self.response(404, "not found path: {}".format(url_path))
        else:
            if url_path.find('/get_video') != 0:
                self.response(404, "not found path: {}".format(url_path))
                return
            param_dict = {}
            for param_pair in params.split('&'):
                #print(param_pair)
                key, value = param_pair.split('=')
                param_dict[key] = value

            ip = param_dict.get('ip')
            if not ip:
                error_msg = "not found param: ip"
                print(error_msg)
                self.response(500, error_msg)
                return
            if ip in video_dict:
                img_bytes = video_dict[ip]
            else:
                start_catch_video(ip)
                time.sleep(1.5)
                img_bytes = video_dict[ip]
            video_read_time_dict[ip] = time.time()
            self.response(200, img_bytes)

    def response(self, status, msg):
        self.send_response(status)
        self.send_header('Content-Type',
                         'text/plain; charset=utf-8')
        self.end_headers()
        self.wfile.write(msg)


def start_catch_video(ip):
    t1 = threading.Thread(target=getVideoImage, args=(ip,))
    t1.setDaemon(True)
    t1.start()
    t2 = threading.Thread(target=pushVideoImage, args=(ip,))
    t2.setDaemon(True)
    t2.start()


def pushVideoImage(ip):
    mqtt_hostname = "mqtt.ca2dev.zdiai.net"  # specify the hostname of the target MQTT broker
    mqtt_port = 8883

    mqtt_auth = {
        'username': 'mqtt',
        'password': 'zdiai@123'
    }
    mqtt_tls = {
        'ca_certs': "/opt/mqtt/ca-mqtt.ca2dev.zdiai.net.crt",
        'tls_version': ssl.PROTOCOL_TLSv1_2  # use the TLS v1.2
    }
    time.sleep(3)
    while True:
        if ip in  video_dict:
            payload = video_dict[ip]
        else:
            payload = ""
        print(time.time(), "send img...")

        publish.single(
          topic="/40000600/device/anchor/msg/stb2",
          payload=payload,
          hostname=mqtt_hostname,
          client_id="paho-mqtt-test",
          auth=mqtt_auth,
          tls=mqtt_tls,
          port=mqtt_port,
          protocol=mqtt.MQTTv311)
        time.sleep(1)

def getVideoImage(ip):
    if "" == ip:
        return None
    video_url = 'rtsp://admin:zdiai@123@' + ip
    video_read_time_dict[ip] = time.time()
    try:
        capture = cv2.VideoCapture(video_url)
        success, frame = capture.read()
        while True:
            # check last read time
            if time.time() - video_read_time_dict[ip] > 30:
                video_dict.pop(ip)
                return
            # time.sleep(0.2)
            if frame is None:
                capture = cv2.VideoCapture(video_url)
            success, frame = capture.read()
            # print(frame, capture)
            if frame is None:
                continue
            ret, buffer = cv2.imencode('.jpg', frame)
            img_bytes = buffer.tobytes()
            print(ip, time.time(), "new img...")
            video_dict[ip] = img_bytes
    except Exception as e:
        print(e)


def run(server_class=HTTPServer, handler_class=ShellHandler):
    server_address = ('', 18100)
    httpd = server_class(server_address, handler_class)
    print("starting video service...")
    httpd.serve_forever()


if __name__ == '__main__':
    run()
